(function($){
	var KEY = "jforest.table";
	
	var IconColumn=function(options){
		this.options=$.extend({},options);
		this.arrEl = [];
	}
	
	IconColumn.prototype={
		createThEl:function(){return $('<th></th>').html(this.options.title).width(this.options.width);},
		createTdEl:function(table,record,$tr){
			var $td=$('<td></td>').width(this.options.width),icons=[];
			if($.isFunction(this.options.icons)){icons = this.options.icons.apply(table,[record,$tr]);}
			else{icons = this.options.icons;}
			$.each(icons,function(i,item){
				$a = $('<a href="javascript:void(0);" style="margin-right:10px;"></a>');
				if(item.icon){$a.append('<i class="fa '+item.icon+'"></i>');}
				if(item.tooltip){if(item.icon){$a.tooltip({title:item.tooltip});}else{$a.html(item.tooltip)}}
				$a.appendTo($td).click(function(e){item.click.apply(table,[record,$tr,e]);});
			});
			this.arrEl.push($td);return $td;
		}
	}
	
	
	var Column = function(options){
		this.options = $.extend({
			data:[],
			values:null,
			format:null, //function
			click:null, //function
			detailFormat:null //function
		},options);
	}
	
	Column.prototype = {
		createThElement:function(table,i){
			this.$el = $('<th></th>');
			var self = this;
			if(this.options.checkbox){
				var $checkbox = $('<label class="nice-checkbox"><input type="checkbox"></label>');
				$checkbox.mousedown(function(event){
					$(this).toggleClass('on');
					if($(this).hasClass('on')){
						$.each(self.options.data,function(i,$item){
							$item.find('.nice-checkbox').addClass('on');
							$item.find('.nice-checkbox input[type="checkbox"]')[0].checked = true;
						});
					}else{
						$.each(self.options.data,function(i,$item){
							$item.find('.nice-checkbox').removeClass('on');
							$item.find('.nice-checkbox input[type="checkbox"]')[0].checked = false;
						});
					}
				});
				if(this.options.click){
					$checkbox.find('input[type="checkbox"]').click(function(){
						self.options.click.apply(self,[null]);
					});
				}
				if(this.options.values){
					this.options.values = this.options.values.split(",");
				}
				this.$el.append($checkbox);
			}else {
				this.$el.text(this.options.title);
			}
			if(this.options.width){
				this.$el.width(this.options.width);
			}
			return this;
		},
		createTdElement:function(value){
			var $td = $('<td></td>').html(value);
			if(this.options.width){$td.width(this.options.width);}
			this.options.data.push($td);
			return $td;
		},
		createIconElement:function(record,$tr){
			var $td = $('<td></td>');
			if(this.options.width){$td.width(this.options.width);}
			var icons = [];
			if($.isFunction(this.options.icons)){
				icons = this.options.icons.apply($tr,[record]);
			}else{
				icons = this.options.icons;
			}
			$.each(icons,function(i,obj){
				if(!obj.tooltip){obj.tooltip = '';}
				var $a = $('<a href="javascript:void(0);" style="margin-right:10px;" title="'+obj.tooltip+'"><i class="fa '+obj.icon+'"></i></a>');
				$a.click(function(event){
					obj.click.apply($tr,[record,event]);
				}).tooltip();
				$td.append($a);
			});
			this.options.data.push($td);
			return $td;
		},
		createCheckbox:function(value){
			var self = this;
			var $td = $('<td><label class="nice-checkbox"><input type="checkbox" value="'+value+'"></label></td>');
			if(!this.options.width){this.options.width = 30;}
			$td.width(this.options.width);
			$td.find('.nice-checkbox').mousedown(function(event){
				$(this).toggleClass('on');
			});
			this.options.data.push($td);
			
			if(this.options.click){
				$td.find('.nice-checkbox input[type="checkbox"]').click(function(){
					self.options.click.apply(self,[value]);
				});
			}
			if(this.options.values && $.inArray(value.toString(),this.options.values) > -1){
				$td.find('.nice-checkbox').addClass('on');
				$td.find('.nice-checkbox input[type="checkbox"]')[0].checked = true;
			}
			return $td;
		},
		createDetailElement:function(record,colsNum,$tr){
			var $td = $('<td><a href="javascript:void(0);"><i class="fa fa-plus-square"></i></a></td>');
			if(!this.options.width){this.options.width = 30;}
			$td.width(this.options.width);
			var self = this;
			$td.find('a').click(function(){
				var $detailTr = $td.data('_detailTr');
			
				$(this).find('i').toggleClass('fa-plus-square');
				$(this).find('i').toggleClass('fa-minus-square');
				
				if(!$detailTr){
					$detailTr = $('<tr><td colspan="'+colsNum+'"></td></tr>');
					$detailTr.find('td').html(self.options.detailFormat.apply(self,[record]));
					$td.data('_detailTr',$detailTr);
				}
				
				if($(this).find('i').hasClass('fa-minus-square')){
					$tr.after($detailTr);
				}else{
					$detailTr.remove();
				}
			});
			this.options.data.push($td);
			return $td;
		},
		getCheckboxValues:function(){
			var values = '';
			$.each(this.options.data,function(i,$item){
				var $checkbox = $item.find('.nice-checkbox input[type="checkbox"]');
				if($checkbox[0].checked == true){
					values = values+','+$checkbox.val();
				}
			});
			if(values.length>1){values = values.substring(1);}
			return values;
		}
	}
	
	var Table = function(element,options){
		this.$el = $(element);
		this.options = $.extend({
			autoLoad:true,
			ajax:{},
			pagingEl:'auto',
			paging:{},
			cols:null //{}或[]
		},options);
		if(this.$el.find('thead').length==0){this.$el.append('<thead></thead>');}
		if(this.$el.find('tbody').length==0){this.$el.append('<tbody></tbody>');}
		if(this.$el.find('tfoot').length==0){this.$el.append('<tfoot></tfoot>');}
		this.ajax=jf.getAjax($.extend({param:function(param){
			if(this.paging){var opts=this.paging.options;return {pageNo:opts.pageNo,pageLimit:opts.pageLimit}}
			else{return {};};}},
			this.options.ajax,
			{bindObj:this,callback:function(result){
				if($.isFunction(this.options.ajax.callback)){result=this.options.ajax.callback.apply(this,[result])};
				if(result){if($.isArray(result.data)){this._buildData(result.data);};if(this.paging){this.paging.setData({
					dataTotal:result.dataTotal,pageTotal:result.pageTotal});}}
			}}
		));
		this._buildTitle();var table=this;
		if('auto'==this.options.pagingEl){
			this.options.pagingEl=$('<tr><td colspan="'+this.options.cols.length+'"></td></tr>').appendTo(this.$el.find('tfoot')).find('td');}
		if(this.options.pagingEl){this.paging=$(this.options.pagingEl).jfPaging($.extend(this.options.paging,{
			callback:function(opts){table.ajax.load(function(param){return $.extend(param||{},{pageNo:opts.pageNo,pageLimit:opts.pageLimit});});}
		}));this.paging.$el.addClass('pagination-sm').css('margin',0)}
		//是否自动加载
		if(this.options.autoLoad == true){this.loadData();}
	}
	
	Table.prototype = {
		_buildTitle:function(){
			var cols=this.options.cols||{},col;
			if($.isArray(cols)){
				var $tr=$('<tr></tr>'),cols=this.options.cols,col;
				for(var i=0;i<cols.length;i++){
					if(cols[i].icons){col=new IconColumn(cols[i]);$tr.append(col.createThEl());}
					else{col=new Column(cols[i]);$tr.append(col.createThElement(this,i).$el);}
					this.options.cols[i] = col;
				}
				this.$el.find('thead').append($tr);
			}else{
				var arrCol=[],code,title,width;
				this.$el.find('thead th').each(function(i,th){
					code=$(th).data('data-code'),col=cols[code],title=$(th).html(),width=$(th).width();
					if(col){col=$.extend({code:code,title:title,width:width},col);
						if(col.icons){col=new IconColumn(col)}else{col=new Column(col);}}
					else{col=new Column({code:code,title:title,width:width})}
					arrCol.push(col);
				})
				this.options.cols=arrCol;
			}
		},
		_buildData:function(data){
			this.$el.find('tbody').empty();
			var self = this;
			$.each(data,function(i,record){
				var $tr = $('<tr></tr>');
				$.each(self.options.cols,function(i,col){
					if(col.options.detailFormat){
						$tr.append(col.createDetailElement(record,self.options.cols.length,$tr));
					}else if(col.options.checkbox){
						col.$el.find('.nice-checkbox').removeClass('on');
						if(col.options.format){
							$tr.append(col.createCheckbox(col.options.format.apply(self,[record])));
						}else{
							$tr.append(col.createCheckbox(record[col.options.code]));
						}
					}else if(col.options.icons){
						$tr.append(col.createTdEl(self,record,$tr));
					}else{
						if(col.options.format){
							$tr.append(col.createTdElement(col.options.format.apply(self,[record])));
						}else{
							$tr.append(col.createTdElement(record[col.options.code]));
						}
					}
				});
				self.$el.find('tbody').append($tr);
			})
		},
		loadData:function(setting){
			if(this.ajax.isValid()){this.ajax.load(setting);}
		}
	}
	
	$.fn.jfTable = function(){
		var args = Array.prototype.slice.call(arguments, 0);
		var value = undefined;
		this.each(function () {
			var $this = $(this);
			//throw 'only support table element'
			if (args.length === 0 || typeof(args[0]) === "object") {
				opts = args.length === 0 ? {} : $.extend({}, args[0]);
				$this.data(KEY,new Table(this,opts)); //创建控件
			}else if (typeof(args[0]) === "string"){
				var entity = $this.data(KEY);
                if(entity === undefined){return;}
                value = entity[args[0]].apply(entity, args.slice(1));
			}else{
				 throw 'Invalid arguments to '+KEY+' plugin: ' + args;
			}
	    });
	    return (value === undefined) ? this : value;
	};
	
	$.fn.jfTable.Constructor = Table;
})(window.jQuery)